由于静态数据成员要实际在分配空间,因此不能在类声明中进行初始化。静态数据成员初始化在类的外部进行,且与一般数据成员初始化不同,它的格式如下:<数据类型><类名>::<静态数据成员名>=<值>

静态成员变量:

1)在编译阶段就分配空间。对象还没有创建;

2)必须在类中声明,在类外初始化(或定义)。

3)归同一个类的所有对象所有,共享同一个静态变量。在为对象分配的空间中不包含静态成员所占空间

4)有权限限制:private静态变量和 public静态变量。

private静态变量;在类(print类)外不能访问和操作。 类外访问:print::a;//erro 类外操作:print::a = 6;//erro

public静态变量;在类(print类)外可以访问和操作。 类外访问:print::a;//yes 类外操作:print::a = 6;//yes

5)const 静态成员变量(const static int a = 8);

定义静态变量 const 静态成员变量时,最好在类的内部初始化。

静态变量的调用:

用类名加域作用符: print::a;

用对象名加取址符: class p1; p1.a;

静态成员函数:(主要是为了访问静态变量)

与静态变量一样,在没有创建对象前即可通过类名调用。

1)静态成员函数只能访问 "静态成员变量",不能访问普通成员变量。

2)静态成员函数的使用规则和静态成员变量一样

3)静态成员函数也有使用权限。类外无法访问私有静态函数。

4)普通成员函数可访问"静态成员变量",也可访问"非静态成员变量"

类中可以包含静态数据成员和静态函数成员,统称为静态成员。默认情况下,静态成员的作用域是类范围内且是外部链接的。静态成员在内存中只有一个副本,不是类对象的一部分,而是独立的对象。因此,静态数据成员的声明不是定义,声明在类作用域内完成,而定义在文件作用域内完成。


class BufferedOutput
{
public:
     short BytesWritten()
    { return bytecount;}
    static void ResetCount()
    { bytecout = 0;}
    static long bytecount;
};

long BufferedOutput::bytecount = 8;

静态成员的存在不依赖于对象实例,因此可以使用成员选择符访问,也可以不使用类对象访问。

BufferedOutput Console;

long nBytes = Console.bytecount;

lont nBytes = BufferedOutput::bytecount;

static 成员变量不属于对象的一部份,而是类别的一部份,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量。但首先你必须初始化它。不要把static 成员变量的初始化动作安排在类别的构造式中,因为构造式可能一再被调用,而变量的初值却只应该设定一次。也不要把初始化动作安排在头文件中,因为它可能会被包含许多地方,因此也就可能被执行许多次。你应该在实作档中且类别以外的任何位置设定其初值。例如在main 之中,或全域函数中,或任何函数之外:

double SavingAccount::m_rate = 0.0075; // 设立static 成员变量的初值

void main() { ... }

对于静态(static)对象,当对象诞生时其构造式被执行;当程序将结束时(此对象因而将遭致毁灭)其析构式才被执行,但比全域对象的析构式早一步执行。

但静态数据成员属于类,因此定义对象时并不为静态成员分配空间。

为静态成员分配空间称为静态成员的定义

静态成员的定义一般出现在类的实现文件中。如在SavingAccount类的实现文件中,必须要如下的定义:

double SavingAccount::rate = 0.05;

该定义为rate分配了空间,并给它赋了一个初值0.05。

如果没有这个定义,连接器会报告一个错误。

可以通过作用域操作符从类直接调用。如: SavingAccount::rate

但从每个对象的角度来看,它似乎又是对象的一部分,因此又可以从对象引用它。如有个SavingAccount类的对象obj,则可以用:obj.rate

由于是整个类共享的,因此不管用哪种调用方式,得到的值都是相同的

定义静态成员函数的主要目的是访问静态的数据成员。

如在SavingAccount类中,当利率发生变化时,必须修改这个静态数据成员的值。为此可以设置一个静态的成员函数

static void SetRate(double newRate) {rate = newRate;}

静态成员函数可定义为内嵌的,也可在类外定义。在类外定义时,不用static。

静态成员函数的访问:可以通过类作用域限定符或通过对象访问

类名::静态成员函数名()

静态数据成员有什么特征?有什么用途?

不管这个类有多少个对象,静态数据成员都只有一份拷贝。静态数据成员一般用来保存整个类所有对象共享的信息。

常量数据成员和静态常量数据成员有什么区别?如何初始化常量数据成员?如何初始化静态常量数据成员?

常量的数据成员指得是那些在对象生成时给定了初值,在整个对象的生命周期中,该数据成员的值是不能变的。常量数据成员的值必须在构造函数的初始化列表中进行初始化。静态的常量数据成员是整个类所有对象共享的一个常量。对整个类而言,不管定义了多少个对象,该成员永远只有一份拷贝。静态常量数据成员的值是在定义类时给定。

静态成员函数不能操作非静态的数据成员,那么非静态的成员函数能否操作静态的数据成员?为什么?

因为静态成员函数没有隐含的this指针,所以不能够操作非静态的数据成员。静态的数据成员是所有对象共享的数据成员,在逻辑上是属于每一个对象的,所以非静态的成员函数可以操作静态的数据成员。

静态成员变量的初始化不能放在类的构造函数中;

为静态成员分配空间称为静态成员的定义

静态成员的定义一般出现在类的实现文件中。如在SavingAccount类的实现文件中,必须要如下的定义:

double SavingAccount::rate = 0.05;

该定义为rate分配了空间,并给它赋了一个初值0.05。

如果没有这个定义,连接器会报告一个错误。

static关键字的作用

(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值。

(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其他函数访问。

(3)在模块内的static函数只可以被这一模块内的其他函数调用。这个函数的使用范围被限制在声明它的模块内。

(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。

(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

2

静态成员的好处就是内存中只有一份拷贝,可以直接通过类名访问。